#include "usb_find.h"
#include <stdbool.h>
#include <dirent.h>
#include <stdio.h>
#include <sys/stat.h> 
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#include <errno.h>

#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>


#define USB_DEVICE_PATH "/sys/bus/usb/devices"
#define MAX_PATH 256

//#define T_DEBUG
#define USBID_LEN 4
int LOGE(const char *fmt, ...)
{
#if defined(T_DEBUG)
    int ret;
    va_list ap;
    va_start(ap, fmt);
    printf("\r\n");
    ret = vprintf(fmt, ap);
    va_end(ap);
    return ret;
#else
    return 0;
#endif
}
int LOGD(const char *fmt, ...)
{
#if defined(T_DEBUG)
    int ret;
    va_list ap;
    va_start(ap, fmt);
    printf("\r\n");
    ret = vprintf(fmt, ap);
    va_end(ap);
    return ret;
#else
    return 0;
#endif
}
int LOGIMPORT(const char *fmt, ...)
{
    int ret;
    va_list ap;
    va_start(ap, fmt);
    printf("\r\n");
    ret = vprintf(fmt, ap);
    va_end(ap);
    return ret;
}




char*   FindUsbDevice(unsigned int vendor_id_dist ,unsigned int product_id_dist ,unsigned int device_interface_id ,unsigned int deeptype)
{
    DIR *pDir;
    DIR *pDirA;
    int fd;
    char filename[MAX_PATH];
    bool usb_device_found = false;
    struct stat statbuf;
    struct dirent* ent = NULL;
    char dir[MAX_PATH] = USB_DEVICE_PATH;
    char dirA[MAX_PATH] = USB_DEVICE_PATH;

    unsigned int vendor_id;
    unsigned int product_id;
    char idVendor[USBID_LEN + 1] = {0};
    char idProduct[USBID_LEN + 1] = {0};

    char usb_device_prefix[MAX_PATH] = {0};

    LOGE("FindUsbDevice %x",device_interface_id);
    
    if ((pDirA = opendir(dirA)) == NULL)  {
        LOGE("Cannot open directory:%s/", dirA);  
        return 0;
    }

    LOGD("find VENDOR_ID!" );
    
    /*first: find the entity contain the Suitable verdor and product id*/   
    while ((ent = readdir(pDirA)) != NULL)  {        
        sprintf(filename, "%s/%s", dirA, ent->d_name);
        LOGD("file name %s\n",ent->d_name);
        lstat(filename, &statbuf);

        

        if (S_ISLNK(statbuf.st_mode))  {

            
            
            sprintf(filename, "%s/%s/idVendor", dirA, ent->d_name);
            LOGD("first stage start found %s!", filename);
            fd = open(filename, O_RDONLY);
            if (fd > 0) {
                read(fd, idVendor, USBID_LEN);
                close(fd);

                sscanf(idVendor, "%x", &vendor_id);
                
                LOGD("first stage get vendor id %s!", idVendor);
                if(vendor_id != vendor_id_dist)
                    continue;
                // 发现vid
            }
            else
            {
                continue;
            }
            
            sprintf(filename, "%s/%s/idProduct", dirA, ent->d_name);
            LOGD("find PRODUCT_ID! %s",filename );
            fd = open(filename, O_RDONLY);
            if (fd > 0) {
                read(fd, idProduct, USBID_LEN);
                close(fd);

                sscanf(idProduct, "%x", &product_id);
                
                LOGD("first stage get product id %s!", idProduct);
                
                if(product_id != product_id_dist)
                    continue;
                // 发现pid
                LOGD("first stage success %s!", ent->d_name);
                
                usb_device_found = false;
                // 进入interface id
                sprintf(usb_device_prefix, "%s:1.%d", ent->d_name, device_interface_id);
                
                pDir = opendir(dirA);
                
                LOGD("usb_device_prefix %s", usb_device_prefix);
                
                while ((ent = readdir(pDir)) != NULL)  {
                    
                    sprintf(filename, "%s/%s", dirA, ent->d_name);
                    lstat(filename, &statbuf);
                    LOGD("usb_device_prefix  filename %s", filename);
                    if (S_ISLNK(statbuf.st_mode))  {
                    
                        LOGD("first second start found %s!", ent->d_name);

                        if(!strcmp(ent->d_name, usb_device_prefix))
                        {   
                            usb_device_found = true;
                            break;
                        }
                    }
                }

                
                closedir(pDir);

                if(!usb_device_found || ent->d_name[0] == '\0')
                    return NULL;
                
                /*second: get device name */
                usb_device_found = false;
                memset(dir,0,MAX_PATH); 
                memcpy(dir,USB_DEVICE_PATH,strlen(USB_DEVICE_PATH));
                strcat(dir, "/");
                strcat(dir, ent->d_name);

                
                LOGD("the file name %s", ent->d_name);
                
                pDir = opendir(dir);
                
                while ((ent = readdir(pDir)) != NULL)  {
                    sprintf(filename, "%s/%s", dir, ent->d_name);
                    LOGD("dname %s\n",filename);
                    if(deeptype > 0 )
                    {
                        if(!strncmp(ent->d_name, "tty", strlen("tty")))
                        {
                            // 发现tty 设备
                            strcat(dir, "/");
                            strcat(dir, ent->d_name);
                            pDir = opendir(dir);

                            while ((ent = readdir(pDir)) != NULL)  {
                                sprintf(filename, "%s/%s", dir, ent->d_name);

                                if(!strncmp(ent->d_name, "ttyACM", strlen("ttyACM")))
                                {
                                    // 发现ttyACM 设备
                                    LOGIMPORT("Download %s\n",ent->d_name);
                                    usb_device_found = true;
                                    sleep(1);
                                    break;
                                }

                            }
                            break;
                        }


                    }
                    else
                    {
                        if(!strncmp(ent->d_name, "ttyUSB", strlen("ttyUSB")))
                        {
                            LOGIMPORT("AT %s\n",ent->d_name);
                            usb_device_found = true;
                            sleep(1);
                            break;
                        }
                    }

                }
                
                continue;
            }
            else
            {
                continue;
            }

        }   
    }

    
    closedir(pDir);
    
    if(usb_device_found)
        return ent->d_name;
    else
        return NULL;
    
    return NULL;
}
